package org.ectar.papi.data
{
	import mx.collections.ArrayCollection;
	
	/**
	 * 
	 * @author Mykhaylo Lytvynyuk
	 * 
	 * Object contains a number of methods which do necessary job to process
	 * Google Data Atom feeds into more sophisticated entiities such as Objects 
	 * of different type.
	 * 
	 * Typical usage is to give in parameter XML feed - receive as return populated object
	 * 
	 */
	public class GDataHelper
	{
		// Define and use atom namespace
        private namespace atom = "http://www.w3.org/2005/Atom";
        use namespace atom;
        
        private namespace media = "http://search.yahoo.com/mrss/" ;
        use namespace media;
        
        private namespace gphoto = "http://schemas.google.com/photos/2007" ;
        use namespace gphoto;
        
		private namespace exif = "http://schemas.google.com/photos/exif/2007";
		use namespace exif;
        
        //xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gphoto="http://schemas.google.com/photos/2007">
		
		/**
		 * Parses XML feed of album entry and return populated object
		 *  
		 * @param xml - XML feed
		 * @return - populated instance of GAlbum object
		 * 
		 */
		public static function parseAlbum(xml:XML):GAlbum {
			var album:GAlbum = new GAlbum();
			
			
			album.id = xml.id;
			//photo.category = xml.categoory; // @TODO - figure out what a heck is this
			album.title = xml.title;			
			album.published = xml.published;
			album.updated = xml.updated;
			album.summary = xml.summary;
			album.rights = xml.rights;
			album.title = xml.title;
			
			/* Parsing links */
			var links:ArrayCollection = new ArrayCollection();
			
			// gphoto section
			album.gphoto = parseGphoto(xml);
			
			// media section
			album.icon =  xml.media::group.media::content.@url; // @TODO will be removed
			album.media = parseMedia(xml);
			
			for each (var item1:XML in xml.link) {
				var link:Link = new Link();
				
				link.href = item1.@href;
				link.rel = item1.@rel;
				link.type = item1.@type;
								
				links.addItem(link);
			}
			
			album.link = links;	// @TODO Figure out proper usage of this links	
			
			var itemX:XMLList = xml.entry;
			
			if(itemX.length() != 0) {
				var photos:ArrayCollection = new ArrayCollection();
				
				for each (var item:XML in xml.entry) {
					var photo:GFoto = parsePhoto(item);
					photos.addItem(photo);
				}
				
				album.photos = photos;				
			}
			return album;
		}
		
		
		/**
		 * Parses XML feed of albums entries and return an Array of objects
		 *  
		 * @param xml - XML feed
		 * @return -an ArrayCollection of GAlbum instances
		 * 
		 */
		public static function parseAlbums(xml:XML):ArrayCollection {
			
			var albums:ArrayCollection = new ArrayCollection();
			
			for each (var item:XML in xml.entry) {
				var album:GAlbum = new GAlbum();
				album = parseAlbum(item);
				albums.addItem(album);
			}
			
			return albums;
		}
		
		
		/**
		 * Parses XML feed of photograph entry and return populated object
		 *  
		 * @param xml - XML feed
		 * @return - populated instance of GPhoto object
		 * 
		 */
		public static function parsePhoto(xml:XML):GFoto {
			
			var photo:GFoto = new GFoto();
			
			photo.id = xml.id;
			//photo.category = xml.categoory; // @TODO - figure out what a heck is this
			photo.title = xml.title;			
			photo.published = xml.published;
			photo.updated = xml.updated;
			photo.summary = xml.summary;
			photo.content = xml.content;
			
			/* Parsing links */
			var links:ArrayCollection = new ArrayCollection();
			
			for each (var item1:XML in xml.link) {
				var link:Link = new Link();
				
				link.href = item1.@href;
				link.rel = item1.@rel;
				link.type = item1.@type;
								
				links.addItem(link);
			}
			
			photo.link = links;	// @TODO Figure out proper usage of this links	
			
			// gphoto section
			photo.gphoto = parseGphoto(xml);
			
			// media section
			photo.icon =  xml.media::group.media::content.@url; // @TODO will be removed
			photo.media = parseMedia(xml);
			
			// Exif section
			photo.exif = parseExif(xml.exif);
				
			return photo;
		}
		
		
		/**
		 * Parses XML feed of photographs entries and return populated object
		 * 
		 * @param xml - XML feed
		 * @return - an ArrayCollection of GPhoto instances
		 * 
		 */
		public static function parsePhotos(xml:XML):ArrayCollection {
			var photos:ArrayCollection = new ArrayCollection();
			
			for each (var item:XML in xml.entry) {
				var photo:GFoto = parsePhoto(item);				
				photos.addItem(photo);
			}
			
			return photos;
		}
		
		/**
		 *  Parses XML feed of photographs EXIF information and return populated object
		 *  
		 * @param xml - XML feed
		 * @return  - populated instance of GExif object
		 * 
		 */
		public static function parseExif(xml:XMLList):GExif {
			var exifOb:GExif = new GExif();
			exifOb.exposure = xml.exif::exposure;
			exifOb.flash = xml.exif::flash;
			exifOb.focallength = xml.exif::focallength;
			exifOb.fstop = xml.exif::fstop;
			exifOb.imageUniqueID = xml.exif::imageUniqueID;
			exifOb.iso = xml.exif::iso;
			exifOb.make = xml.exif::make;
			exifOb.model = xml.exif::model;
			exifOb.time = xml.exif::time;			
			return exifOb;
		}
		
		private static function parseGphoto(xml:XML):GPhoto {
			// gphoto section
			var gph:GPhoto = new GPhoto();
			
			gph.id = xml.gphoto::id;
			gph.version = xml.gphoto::version;
			gph.albumid = xml.gphoto::albumid;
			gph.width = xml.gphoto::width;
			gph.height = xml.gphoto::height
			gph.client = xml.gphoto::client;
			gph.checksum = xml.gphoto::checksum;
			gph.timestamp = xml.gphoto::timestamp;
			gph.commentCount = xml.gphoto::commentCount;
			gph.commentingEnabled = xml.gphoto::commentingEnabled;	
			gph.name = xml.gphoto::name;
			gph.location = xml.gphoto::location;
			gph.access = xml.gphoto::access;
			gph.numphotos = xml.gphoto::numphotos;
			gph.numphotosremaining = xml.gphoto::numphotosremaining;
			gph.user = xml.gphoto::user;
			gph.nickname = xml.gphoto::nickname;
			gph.rotation = xml.gphoto::rotation;
			gph.position = xml.gphoto::position;
			gph.bytesUsed = xml.gphoto::bytesUsed;
			gph.photoid = xml.gphoto::photoid;
			gph.weight = xml.gphoto::weight;
			
						
			return gph;
		}
		
		private static function parseMedia(xml:XML):GMedia {
			
			var mediaData:GMedia = new GMedia();
			
			mediaData.title =  xml.media::group.media::title;
			mediaData.description = xml.media::group.media::description;
			
			// Parsing keywords
			var keywords:ArrayCollection = new ArrayCollection();
			
			for each (var item2:XML in xml.media::group.media::keywords) {
				var keyword:String;
				
				keyword = item2;
								
				keywords.addItem(keyword);
			}
			mediaData.keywords = keywords;
							
			// Parsing thumbnails
			var thumbnails:ArrayCollection = new ArrayCollection();
			
			for each (var item3:XML in xml.media::group.media::thumbnail) {
				var thumbnail:GThumbnail = new GThumbnail()
				
				thumbnail.url = item3.@url;
								
				thumbnails.addItem(thumbnail);
			}
			mediaData.thumbnail = thumbnails;
			
			
			mediaData.content.url = xml.media::group.media::content.@url;
			mediaData.content.height = xml.media::group.media::content.@height;
			mediaData.content.width = xml.media::group.media::content.@width;
			mediaData.content.type = xml.media::group.media::content.@type;
			mediaData.content.medium = xml.media::group.media::content.@medium;
															
			mediaData.credit = xml.media::group.media::credit;
			
			return mediaData;
		}
	}
}